/******************************************************************************
 * Copyright (C) 2009 Low Heng Sin                                            *
 * Copyright (C) 2009 Idalica Corporation                                     *
 * This program is free software; you can redistribute it and/or modify it    *
 * under the terms version 2 of the GNU General Public License as published   *
 * by the Free Software Foundation. This program is distributed in the hope   *
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.           *
 * See the GNU General Public License for more details.                       *
 * You should have received a copy of the GNU General Public License along    *
 * with this program; if not, write to the Free Software Foundation, Inc.,    *
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.                     *
 *****************************************************************************/
package org.compiere.apps.form;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

import org.compiere.apps.ConfirmPanel;
import org.compiere.apps.IProcessParameter;
import org.compiere.apps.ProcessCtl;
import org.compiere.apps.ProcessParameterPanel;
import org.compiere.apps.Waiting;
import org.compiere.apps.search.Info;
import org.compiere.grid.ed.VDate;
import org.compiere.grid.ed.VLookup;
import org.compiere.model.MColumn;
import org.compiere.model.MLookup;
import org.compiere.model.MLookupFactory;
import org.compiere.model.MPInstance;
import org.compiere.model.MProcess;
import org.compiere.model.X_A_Asset;
import org.compiere.plaf.CompiereColor;
import org.compiere.process.ProcessInfo;
import org.compiere.process.ProcessInfoParameter;
import org.compiere.swing.CPanel;
import org.compiere.util.ASyncProcess;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Trx;

public class A_InternalMovementForm implements FormPanel, ActionListener, VetoableChangeListener, ASyncProcess
{
	private CPanel panel = new CPanel();
	public DecimalFormat format = DisplayType.getNumberFormat(DisplayType.Amount);
	/**	Logger			*/
	public static CLogger log = CLogger.getCLogger(VAssetTransfer.class);
	private List<ProcessInfoParameter> po = new ArrayList<ProcessInfoParameter>();
	private Waiting	m_waiting;
	ASyncProcess m_parent;
	public boolean  m_isLocked = false;
	public int m_AD_Process_ID;
	public int  m_C_BPartner_ID ;
	public String  m_DocNo = "";
	public String Description = "";
	public Timestamp transferDate = null;
	public int m_A_Asset_ID = 0;
	public int	m_New_A_Location_ID = 0;
	
	/**
	 *	Initialize Panel
	 *  @param WindowNo window
	 *  @param frame frame
	 */
	public void init (int WindowNo, FormFrame frame)
	{
		m_WindowNo = WindowNo;
		m_frame = frame;
		Env.setContext(Env.getCtx(), m_WindowNo, "IsSOTrx", "Y");   //  defaults to no
		try
		{
			dynInit();
			jbInit();
			frame.getContentPane().add(mainPanel, BorderLayout.CENTER);
		}
		catch(Exception e)
		{
			log.log(Level.SEVERE, "", e);
		}
	}	//	init

	/**	Window No			*/
	private int         m_WindowNo = 0;
	/**	FormFrame			*/
	private FormFrame 	m_frame;

	private CPanel 			mainPanel = new CPanel();
	private BorderLayout 	mainLayout = new BorderLayout();
	
	private CPanel 			parameterPanel = new CPanel();
	private GridBagLayout 	parameterLayout = new GridBagLayout();
	
	private JLabel 			bpartnerLabel = new JLabel();
	private VLookup 		bpartnerSearch = null;
	
	private VLookup 		docNoSearch = null;
	private JLabel 			docNoLabel = new JLabel();

	private JLabel 			dateLabel = new JLabel();
	private VDate 			dateField = new VDate();
	
	private JLabel			assetlabel = new JLabel();
	private VLookup			assetSearch = null;

	private JLabel			locationLabel = new JLabel();
	private VLookup			locationSearch = null;
	
	private JButton bGenerate = ConfirmPanel.createOKButton(true);
	private JButton bCancel = ConfirmPanel.createCancelButton(true);
	/**
	 *  Static Init
	 *  @throws Exception
	 */
	private void jbInit() throws Exception
	{
		CompiereColor.setBackground(panel);
		//
		mainPanel.setLayout(mainLayout);
		parameterPanel.setLayout(parameterLayout);
		bpartnerLabel.setText("Ответственное лицо:"); 
		docNoLabel.setText(Msg.getMsg(Env.getCtx(), "DocumentNo"));
		dateLabel.setText(Msg.translate(Env.getCtx(), "MovementDate"));
		assetlabel.setText(Msg.getMsg(Env.getCtx(), "A_Asset_ID"));
		locationLabel.setText("Местоположение");
		mainPanel.add(parameterPanel, BorderLayout.NORTH);

		parameterPanel.add(bpartnerLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
			,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		
		parameterPanel.add(bpartnerSearch, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0
				,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		
		parameterPanel.add(docNoLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
				, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		
		parameterPanel.add(docNoSearch, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0
				, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		
		parameterPanel.add(dateLabel, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0
			,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		parameterPanel.add(dateField, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0
			,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		
		parameterPanel.add(assetlabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0
				,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		parameterPanel.add(assetSearch, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0
				,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		
		parameterPanel.add(locationLabel, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0
				, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		parameterPanel.add(locationSearch, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0
				,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		
		parameterPanel.add(bGenerate, new GridBagConstraints(5, 6, 1, 1, 0.0, 0.0
				, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		
		parameterPanel.add(bCancel, new GridBagConstraints(6, 6, 1, 1, 0.0, 0.0
				, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		

	}   //  jbInit

	/**
	 * 	Dispose
	 */
	public void dispose()
	{
		if (m_frame != null)
			m_frame.dispose();
		m_frame = null;
	}	//	dispose

	/**
	 *  Dynamic Init (prepare dynamic fields)
	 *  @throws Exception if Lookups cannot be initialized
	 */
	public void dynInit() throws Exception
	{
			//  BPartner (Agent)
			int AD_Column_ID = 14096;        //  A_Asset.C_BPartnerSR_ID
			MLookup lookupBP = MLookupFactory.get (Env.getCtx(), m_WindowNo, 0, AD_Column_ID, DisplayType.Table);
			bpartnerSearch = new VLookup("C_BPartnerSR_ID", true, false, true, lookupBP);
			bpartnerSearch.addVetoableChangeListener(this);
			//  Document Number  A_InternalMovement.DocumentNo
			AD_Column_ID = MColumn.getColumn_ID("A_InternalMovement", "DocumentNo");
			MLookup lookupDN = MLookupFactory.get (Env.getCtx(), m_WindowNo, 0, AD_Column_ID, DisplayType.Table);
			docNoSearch = new VLookup("DocumentNo", false, false, true, lookupDN);
			docNoSearch.addVetoableChangeListener(this);
			//  Transfer Date 
			dateField.setValue(Env.getContextAsDate(Env.getCtx(), "#Date"));
			dateField.setMandatory(true);
			transferDate = (Timestamp)Env.getContextAsDate(Env.getCtx(), "#Date");
			dateField.addVetoableChangeListener(this);
			// Asset List
			AD_Column_ID = 8070;
			MLookup lookupAsset = MLookupFactory.get (Env.getCtx(), m_WindowNo, 0, AD_Column_ID, DisplayType.Search);
			assetSearch = new VLookup("A_Asset_ID", true, false, true, lookupAsset);
			assetSearch.addVetoableChangeListener(this);
			//Asset location
			AD_Column_ID = 1003725;
			MLookup lookupLocation = MLookupFactory.get(Env.getCtx(), m_WindowNo, 0, AD_Column_ID, DisplayType.TableDir);
			locationSearch = new VLookup("A_Location_ID", false, false, true, lookupLocation);
			locationSearch.addVetoableChangeListener(this);
			
			bGenerate.addActionListener(this);
			bCancel.addActionListener(this);
			
			String sql_ = "SELECT AD_Process_ID FROM AD_Process WHERE LOWER(value) LIKE 'a_internalmovement'";
			PreparedStatement pstmt = null;
	        ResultSet rs = null;
	        try{
	        	pstmt = DB.prepareStatement(sql_, null);
				rs = pstmt.executeQuery();
				while (rs.next()){
					m_AD_Process_ID = rs.getInt(1);
				}
	        }catch(SQLException ee){
	        	
	        	log.log(Level.SEVERE, sql_, ee);
	        	
	        }finally{
	        	
	        	DB.close(rs, pstmt);
				rs = null; pstmt = null;
	        }
			
	}   //  dynInit
	
	/**************************************************************************
	 *  Action Listener.
	 *  @param e event
	 */
	public void actionPerformed(ActionEvent e)
	{	
		log.config("");
		if(e.getSource().equals(bCancel)){
			dispose();
		}
		else if (e.getSource().equals(bGenerate)){

			ProcessInfo pi = new ProcessInfo (m_frame.getTitle(), m_AD_Process_ID);
			
			po.clear();
			po.add(new ProcessInfoParameter("A_Asset_ID",new BigDecimal(m_A_Asset_ID),null,"",""));
			po.add(new ProcessInfoParameter("DateMoved",(Timestamp)dateField.getValue(),null,"",""));
			po.add(new ProcessInfoParameter("C_BPartnerSR_ID",new BigDecimal(m_C_BPartner_ID),null,"",""));
			po.add(new ProcessInfoParameter("A_Location_ID",(Integer)locationSearch.getValue(),null,"",""));
			po.add(new ProcessInfoParameter("Description",new String(Description),null,"",""));
			po.add(new ProcessInfoParameter("DocumentNo",(String)docNoSearch.getValue(),null,"",""));
			
			ProcessInfoParameter[] pp = new ProcessInfoParameter[po.size()];
			po.toArray(pp);
			pi.setParameter(pp);
			
			ProcessParameterPanel pu = new ProcessParameterPanel(m_WindowNo, pi);
			
			ProcessCtl.process(this, m_WindowNo, (IProcessParameter) pu, pi, null);
			
		}
	}   //  actionPerformed
	
	@Override
	public void vetoableChange(PropertyChangeEvent e)
			throws PropertyVetoException {
		String name = e.getPropertyName();
		Object value = e.getNewValue();
		log.config(name + "=" + value);
		
		if (value == null)
			return;
		//  BPartner
		if (name.equals("C_BPartnerSR_ID"))
		{
			bpartnerSearch.setValue(value);
			m_C_BPartner_ID = ((Integer)value).intValue();
			Env.setContext(Env.getCtx(), m_WindowNo, "C_BPartnerSR_ID", m_C_BPartner_ID);
			String sqlDocNo = " SELECT HRM_Number, Name FROM HRM_Order WHERE HRM_OrderType = '1' "
					+" AND HRM_Order_ID IN (SELECT HRM_Order_ID FROM HRM_Employee WHERE C_BPartner_ID = "+m_C_BPartner_ID+" )";
			PreparedStatement pstmt = null;
	        ResultSet rs = null;
	        try{
	        	pstmt = DB.prepareStatement(sqlDocNo, null);
				rs = pstmt.executeQuery();
				while (rs.next()){
						
					docNoSearch.setValue(rs.getString(1));
					Description = rs.getString(2);
				}
	        }catch(SQLException ee){
	        	
	        	log.log(Level.SEVERE, sqlDocNo, ee);
	        	
	        }finally{
	        	
	        	DB.close(rs, pstmt);
				rs = null; pstmt = null;
	        }
		}
		else if (name.equals("DocumentNo")){
			docNoSearch.setValue(value);
			m_DocNo = value.toString();
		}
		else if (name.equals("A_Asset_ID")){
			assetSearch.setValue(value);
			m_A_Asset_ID = ((Integer)value).intValue();
			String sqlLocation = "SELECT A_Location_ID FROM A_Asset WHERE A_Asset_ID = "+ m_A_Asset_ID;
			 PreparedStatement pstmt = null;
		     ResultSet rs = null;
		     try{
		    	 pstmt = DB.prepareStatement(sqlLocation, null);
		    	 rs = pstmt.executeQuery();
		    	 while(rs.next())
		    		 locationSearch.setValue(rs.getInt(1));
		    	 
		     }catch(SQLException ee){
		    	 log.log(Level.SEVERE, sqlLocation, ee);
		     }finally{
		    	 DB.close(rs, pstmt);
		    	 rs = null; pstmt =null;
		     }
			
		}
		else if (name.equals("A_Location_ID")){
			
			locationSearch.setValue(value);
			m_New_A_Location_ID = ((Integer)value).intValue();
			
		}
		
	}

	@Override
	public void lockUI(ProcessInfo pi) {
		JFrame frame = Env.getFrame((Container)m_parent);
		m_waiting = new Waiting (frame, Msg.getMsg(Env.getCtx(), "Processing"), false, pi.getEstSeconds());
		panel.setEnabled(false);
		m_isLocked = true;
		
	}

	@Override
	public void unlockUI(ProcessInfo pi) {
		if (m_waiting != null)
			m_waiting.dispose();
		m_waiting = null;
		m_frame.dispose();
	}

	@Override
	public boolean isUILocked() {
		
		return m_isLocked;
	}

	@Override
	public void executeASync(ProcessInfo pi) {
		// TODO Auto-generated method stub
		
	}
}